home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1991
/
03
/
80x86.asc
< prev
next >
Wrap
Text File
|
1991-02-15
|
6KB
|
165 lines
_80x86 OPTIMIZATION_
by Michael Abrash
[LISTING ONE]
; Copies one string to another string, converting all characters to
; uppercase in the process, using a loop containing LODSB and STOSB.
; Adapted from Zen of Assembly Language, by Michael Abrash; not a
; standalone program, but designed to be used with the Zen timer from
; that book via the Zen timer's PZTIME.BAT batch file: ZTimerOn starts
; the clock, ZTimerOff stops it, and the test-bed program linked in by
; PZTIME.BAT starts the program, reports the results, and ends.
jmp Skip ;skip over data in CS and subroutine
SourceString label word ;sample string to copy
db 'This space intentionally left not blank',0
DestString db 100 dup (?) ;destination for copy
; Copies one zero-terminated string to another string,
; converting all characters to uppercase.
; Input: DS:SI = start of source string; DS:DI = start of destination buffer
; Output: none
; Registers altered: AX, BX, SI, DI, ES
; Direction flag cleared
CopyStringUpper:
mov ax,ds
mov es,ax ;for STOS
mov bl,'a' ;set up for fast register-register
mov bh,'z' ; comparisons
cld
StringUpperLoop:
lodsb ;get next character and point to following character
cmp al,bl ;below 'a'?
jb IsUpper ;yes, not lowercase
cmp al,bh ;above 'z'?
ja IsUpper ;yes, not lowercase
and al,not 20h ;is lowercase-make uppercase
IsUpper:
stosb ;put character into new string and point to
; following location
and al,al ;is this the zero that marks end of the string?
jnz StringUpperLoop ;no, do the next character
ret
; Calls CopyStringUpper to copy & convert SourceString->DestString.
Skip:
call ZTimerOn ;start timing
mov si,offset SourceString ;point SI to the string to copy from
mov di,offset DestString ;point DI to the string to copy to
call CopyStringUpper ;copy & convert to uppercase
call ZTimerOff ;stop timing
[LISTING TWO]
; Copies one string to another string, converting all characters to
; uppercase in the process, using no string instructions.
; Not a standalone program, but designed to be used with the Zen
; timer, as described in Listing 1.
jmp Skip ;skip over data in CS and subroutine
SourceString label word ;sample string to copy
db 'This space intentionally left not blank',0
DestString db 100 dup (?) ;destination for copy
; Copies one zero-terminated string to another string,
; converting all characters to uppercase.
; Input: DS:SI = start of source string; DS:DI = start of destination string
; Output: none
; Registers altered: AL, BX, SI, DI
CopyStringUpper:
mov bl,'a' ;set up for fast register-register
mov bh,'z' ; comparisons
StringUpperLoop:
mov al,[si] ;get the next character and
inc si ; point to the following character
cmp al,bl ;below 'a'?
jb IsUpper ;yes, not lowercase
cmp al,bh ;above 'z'?
ja IsUpper ;yes, not lowercase
and al,not 20h ;is lowercase-make uppercase
IsUpper:
mov [di],al ;put the character into the new string and
inc di ; point to the following location
and al,al ;is this the zero that marks the end of the string?
jnz StringUpperLoop ;no, do the next character
ret
; Calls CopyStringUpper to copy & convert SourceString->DestString.
Skip:
call ZTimerOn
mov si,offset SourceString ;point SI to the string to copy from
mov di,offset DestString ;point DI to the string to copy to
call CopyStringUpper ;copy & convert to uppercase
call ZTimerOff
[LISTING THREE]
; Clears a buffer using MOV/ADD in a loop.
; Not a standalone program, but designed to be used with the Zen
; timer, as described in Listing 1.
mov dx,2 ;repeat the test code twice, to make
; sure it's in the cache (if there is one)
mov bx,dx ;distance from the start of one word
; to the start of the next
sub ax,ax ;set buffer to zeroes
TestTwiceLoop:
mov cx,1024 ;clear 1024 words starting at address
mov di,8000h ; DS:8000h (this is just unused memory
; past the end of the program)
call ZTimerOn ;start timing (resets timer to 0)
StoreLoop:
mov [di],ax ;clear the current word
add di,bx ;point to the next word
dec cx ;count off words to clear until none
jnz StoreLoop ; remain
call ZTimerOff ;stop timing
dec dx ;count off passes through test code
jz StoreDone ;that was the second pass; we're done
jmp TestTwiceLoop ;that was first pass; do second pass with all
; instructions and data in the cache
StoreDone:
[LISTING FOUR]
; Clears a buffer using MOV/ADD in an unrolled loop.
; Not a standalone program, but designed to be used with the Zen
; timer, as described in Listing 1.
mov dx,2 ;repeat the test code twice, to make
; sure it's in the cache (if there is one)
mov bx,dx ;distance from the start of one word
; to the start of the next
sub ax,ax ;set buffer to zeroes
TestTwiceLoop:
mov si,1024 ;clear 1024 words starting at address
mov di,8000h ; DS:8000h (this is just unused memory
; past the end of the program)
call ZTimerOn ;start timing (resets timer to 0)
mov cl,4 ;divide the count of words to clear by
shr si,cl ; 16, because we'll clear 16 words
; each time through the loop
StoreLoop:
REPT 16 ;clear 16 words in a row without looping
mov [di],ax ;clear the current word
add di,bx ;point to the next word
ENDM
dec si ;count off blocks of 16 words to clear
jnz StoreLoop ; until none remain
call ZTimerOff ;stop timing
dec dx ;count off passes through test code
jz StoreDone ;that was the second pass; we're done
jmp TestTwiceLoop ;that was the first pass; do the second pass
; with all instructions and data in the cache
StoreDone: